#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <error.h>
#include "lqslib.h"

//#define SINGLE_LIST
/* ----------------------------单向链表---------------------------------*/
#ifdef SINGLE_LIST /*{{{*/
typedef struct _element_type {
	char data;
	//...
}element_type;

typedef struct _list_node {
	element_type element;
	struct _list_node *next;
}list_node;

int insert_node(list_node **head_addr, list_node *node);
int get_list_length(list_node *head);
list_node * get_node_pos(list_node *head, int pos);
int free_list(list_node *head);
int remove_node_pos(list_node **head_addr, int pos);
int insert_node_pos(list_node **head_addr, list_node *node, int pos);

int main()
{ 
	int i;
	list_node *head = NULL; /* 只是一个指针变量，所指的第一个结点即为有效结点 */
	list_node *pnode[10] = {0};

	for(i = 0; i < 10; i++)
	{
		pnode[i] = malloc(sizeof(list_node));
		memset(pnode[i], 0, sizeof(list_node));
		if(pnode[i] == NULL) {
			perror("malloc");
		}
		debug_print("pnode[%d] value = %p\n", i, pnode[i]);
	}

#if 0
	for(i = 0; i < 10; i++)
	{
		insert_node(&head, pnode[i]);
	}
#endif

#if 1
	insert_node_pos(&head, pnode[0], 1);
	insert_node_pos(&head, pnode[1], 2);
	insert_node_pos(&head, pnode[2], 3);
	insert_node_pos(&head, pnode[3], 4);
	insert_node_pos(&head, pnode[4], 2);
	insert_node_pos(&head, pnode[5], 3);
	remove_node_pos(&head, 3);
	remove_node_pos(&head, 1);
	insert_node_pos(&head, pnode[6], 2);
	insert_node_pos(&head, pnode[7], 2);
	remove_node_pos(&head, 6);
	insert_node_pos(&head, pnode[8], 6);
	insert_node_pos(&head, pnode[9], 5);
#endif

	free_list(head);
	return 0;
} /*}}}*/

/* Insert node after list head */ /*{{{*/
int insert_node(list_node **head_addr, list_node *node)
{
	if(head_addr == NULL || node == NULL)
		return -1;

	if(*head_addr == NULL)
	{
		debug_print("%s -> %p\n", __FUNCTION__, node);
		*head_addr = node;
	}
	else
	{
		node->next = *head_addr;
		*head_addr = node;
		debug_print("%s -> %p\n", __FUNCTION__, node);
	}
	return 0;
}

int get_list_length(list_node *head)
{
	int length = 0;
	list_node *tmp = head;

	while(tmp != NULL)
	{
		length++;
		tmp = tmp->next;
	}

	return length;
}

/* Return one node that its positon is pos */
list_node * get_node_pos(list_node *head, int pos)
{
	int len = 0;
	int i = 1;
	list_node *tmp = head;

	if(tmp == NULL) {
		return NULL;
	}
	
	len = get_list_length(head);
	if(pos < 1 || pos > len) 
	{
		return NULL;
	}
	else
	{
		while(tmp->next != NULL)
		{
			if(i == pos) {
				break;
			}
			tmp = tmp->next;
			i++;
		}	
	}
	debug_print("%s -> %p\n", __FUNCTION__, tmp);
	return tmp;
}

/* Insert one node at pos, Thus the node position is pos after this function return */
int insert_node_pos(list_node **head_addr, list_node *node, int pos)
{
	list_node *p = NULL;
	list_node *tmp = *head_addr;

	if(tmp == NULL && pos == 1 && node != NULL) {
		insert_node(head_addr, node);
		return 0;
	}

	p = get_node_pos(tmp, pos - 1);
	if(p == NULL) {
		return -1;
	}

	node->next = p->next;
	p->next = node;
	debug_print("%s -> %p\n", __FUNCTION__, node);

	return 0;
}

/* Remove the node at pos */
int remove_node_pos(list_node **head_addr, int pos)
{
	list_node *p = NULL;
	list_node *tmp = NULL;
	list_node *head = *head_addr;

	if(head != NULL && pos == 1) {
		tmp = head;
		*head_addr = head->next;
		debug_print("%s -> %p\n", __FUNCTION__, tmp);
		free(tmp);

		return 0;
	}

	p = get_node_pos(head, pos - 1);
	if(p == NULL) {
		return -1;
	}

	tmp = p->next;
	p->next = p->next->next;
	debug_print("%s -> %p\n", __FUNCTION__, tmp);
	free(tmp);
}

/* Free list */
int free_list(list_node *head)
{
	list_node *tmp = head; 

	if(tmp == NULL)
		return -1;

	while(tmp->next != NULL)
	{
		head = head->next;
		debug_print("%s -> %p\n", __FUNCTION__, tmp);
		free(tmp);
		tmp = head;
	}
	debug_print("%s -> %p\n", __FUNCTION__, tmp);
	free(tmp);

	return 0;
} /*}}}*/

#else
/* ----------------------------双向链表---------------------------------*/

int main()
{
#if 0 //list
	cel_link_t *mylist;
	int num[10] = {0,1,2,3,4,5,6,7,8,9};

	/* 返回一个初始化好的链表，指向一个cel_link_t的变量，link_t变量的head指向
	 * 一个node_t(链表头)和一个node_t(链表尾)，此时link_t的size为0，插入的数据
	 * 会插入 链表头 和链表尾之间，size加1 */ 
	mylist = new_cel_link();
	/* 添加一个节点，节点value的值为num[0]的地址，通过value指针串起需要
	 * 链的数据*/
	cel_link_add_first(mylist, (void *)num + 0);
	cel_link_add_first(mylist, (void *)num + 1);
	cel_link_add_last(mylist, (void *)num + 2);
	cel_link_add_last(mylist, (void *)num + 3);
	cel_link_insert(mylist, 3, (void *)num + 4);
	cel_link_insert(mylist, 3, (void *)num + 5);
	/* 返回已移除节点的value指针，指向用户数据 */
	cel_link_remove_first(mylist);
	cel_link_remove_last(mylist);
	cel_link_remove(mylist, 3);

	free_cel_link(&mylist, NULL);
#endif
	int i;
	struct _test {
		int data;
		char flag;
	}a[80];

	for(i = 0; i < 80; i++)
	{
		a[i].data = i;
	}
#if 0
	cel_queue_t *ptr;
	ptr = new_cel_queue();

	for(i = 0; i < 40; i++)
	{
		cel_queue_en(ptr, &a[i]);
		printf("num = %d\n", cel_queue_length(ptr));
	}
	while(cel_queue_length(ptr) > 0)
	{
		printf("i = %d\n",((struct _test *)cel_queue_de(ptr))->data);	
	}
	free_cel_queue(&ptr, NULL);
#else
	cel_stack_t *ptr;
	ptr = new_cel_stack();

	for(i = 0; i < 40; i++)
	{
		cel_stack_push(ptr, &a[i]);
		printf("num = %d\n", cel_stack_depth(ptr));
	}
	while(cel_stack_depth(ptr) > 0)
	{
		printf("i = %d\n",((struct _test *)cel_stack_pop(ptr))->data);	
	}
	free_cel_stack(&ptr, NULL);
#endif
	return 0;
}/*}}}*/

#endif //SINGLE_LIST




